package random

import (
	"math"
	"math/rand"
	"strconv"
	"strings"
)

// Boolean 返回一个随机的布尔值。
func Boolean(args ...any) bool {
	if len(args) >= 3 {
		var (
			_min = args[0]
			_max = args[1]
			_cur = args[2]
		)
		if _cur != nil {
			cur, ok := _cur.(bool)
			if !ok {
				cur = true
			}
			min, ok := _min.(int)
			if !ok {
				min = 1
			}
			max, ok := _max.(int)
			if !ok {
				max = 1
			}
			if min <= 0 {
				min = 0
			}
			if max <= 0 {
				max = 1
			}

			if rand.Float32() > (1.0 / float32(min+max) * float32(min)) {
				return !cur
			}
			return cur
		}
	}

	return rand.Float32() >= float32(0.5)
}

func Bool(args ...any) bool {
	return Boolean(args...)
}

type Number interface {
	byte | int | int32 | int64 | float32 | float64 | uint | uint32 | uint64
}

// Natural 返回一个随机的自然数（大于等于 0 的整数）。
func Natural[T Number](min, max T) T {
	v := math.Round(rand.Float64() * float64(max-min))
	return T(v) + min
}

// Integer 返回一个随机的整数。
func Integer[T Number](min, max T) T {
	return T(math.Round(rand.Float64()*float64(max-min))) + min
}

func Int(min, max int) int {
	return Integer(min, max)
}

// Float 返回一个随机的浮点数。
func Float(min, max, dmin, dmax int) (r float64) {
	r = float64(Integer(min, max))
	dcount := Natural(dmin, dmax)
	if dcount > 0 {
		var ret []byte
		ret = append(ret, '0')
		ret = append(ret, '.')
		for i := 0; i < dcount; i++ {
			if i < dcount-1 {
				ret = append(ret, Character("number"))
			} else {
				ret = append(ret, Character("123456789"))
			}
		}
		v, _ := strconv.ParseFloat(string(ret), 64)
		r += v
	}

	return r
}

// Character 返回一个随机字符。
func Character(pool string) byte {
	var pools = map[string]string{
		"lower":  "abcdefghijklmnopqrstuvwxyz",
		"upper":  "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
		"number": "0123456789",
		"symbol": "!@#$%^&*()[]",
	}
	pools["alpha"] = pools["lower"] + pools["upper"]
	pools["default"] = pools["lower"] + pools["upper"] + pools["number"] + pools["symbol"]
	if len(pool) == 0 {
		pool = "default"
	}
	s, ok := pools[strings.ToLower(pool)]
	if !ok {
		s = pool
	}
	return s[Natural(0, len(pool)-1)]
}

func Char(pool string) byte {
	return Character(pool)
}

// String 返回一个随机字符串。
func String(pool string, min, max int) string {
	var llen = Natural(min, max)

	var text []byte = make([]byte, 0, llen)

	for i := 0; i < llen; i++ {
		text = append(text, Character(pool))
	}

	return string(text)
}

func Str(pool string, min, max int) string {
	return String(pool, min, max)
}

// Range 返回一个整型数组。
func Range(start, stop, step int) []int {
	var llen = int(math.Max(math.Ceil(float64((stop-start)/step)), 0))

	var rr = make([]int, 0, llen)
	for i := 0; i < llen; i++ {
		rr = append(rr, start)
		start += step
	}

	return rr
}
